Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend replace database in query #210

Merged
merged 18 commits into from
Jul 11, 2024

Conversation

JCZuurmond
Copy link
Member

@JCZuurmond JCZuurmond commented Jul 10, 2024

Improve the database replacement in query by:

  • Making it part of the DashboardMetadata class
  • Allow specifying which database to replace
  • Support replacing catalog
  • Allow specifying which catalog to replace

See https://github.com/databrickslabs/ucx/pull/1920/files/fae429e4d73eceebd7259c9bcaa390e6c7aa4395#r1670960522

Partially resolves #212

Copy link

github-actions bot commented Jul 10, 2024

✅ 35/35 passed, 7 flaky, 2 skipped, 25m25s total

Flaky tests:

  • 🤪 test_dashboard_deploys_dashboard_with_display_name (10.166s)
  • 🤪 test_dashboard_deploys_dashboard_with_counter_variation (12.713s)
  • 🤪 test_dashboard_deploys_dashboard_the_same_as_created_dashboard (13.657s)
  • 🤪 test_dashboard_deploys_dashboard_with_table (11.965s)
  • 🤪 test_dashboards_deploys_dashboard_with_markdown_header (20.283s)
  • 🤪 test_dashboard_deploys_dashboard_with_big_widget (22.139s)
  • 🤪 test_dashboards_deploys_dashboard_with_invalid_query (20.833s)

Running from acceptance #301

def replace_database_in_query(node: sqlglot.Expression, *, database: str) -> sqlglot.Expression:
"""Replace the database in a query."""
if isinstance(node, sqlglot.exp.Table) and node.args.get("db") is not None:
def replace_database_in_query(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rewrite this as a public method on DashboardMetadata: def replace_database(self, catalog_name: str, schema_name: str) -> DashboardMetadata:, which would create a copy of DashboardMetadata, but with all of the queries rewritten with the target catalog/db

src/databricks/labs/lsql/dashboards.py Outdated Show resolved Hide resolved
src/databricks/labs/lsql/dashboards.py Outdated Show resolved Hide resolved
src/databricks/labs/lsql/dashboards.py Outdated Show resolved Hide resolved
@JCZuurmond JCZuurmond requested a review from nfx July 10, 2024 14:23
@JCZuurmond JCZuurmond changed the title Optionally specify which database to replace in query Extend replace database in query Jul 10, 2024
@JCZuurmond JCZuurmond force-pushed the feat/replace-database-in-query-where-existing-database branch 2 times, most recently from 0b51df7 to 7a7366f Compare July 10, 2024 14:29
@JCZuurmond JCZuurmond force-pushed the feat/replace-database-in-query-where-existing-database branch 2 times, most recently from bbc3cb6 to cba91fe Compare July 10, 2024 14:30
@JCZuurmond JCZuurmond force-pushed the feat/replace-database-in-query-where-existing-database branch from c2b2083 to 1ff8635 Compare July 10, 2024 14:42
@JCZuurmond JCZuurmond force-pushed the feat/replace-database-in-query-where-existing-database branch from 1ff8635 to cc4ce27 Compare July 10, 2024 16:17
@@ -216,8 +217,8 @@ def __post_init__(self):
if not self.id:
self.id = self.path.stem if self.path is not None else ""

def update(self, other: "TileMetadata") -> None:
"""Update the tile metadata with another tile metadata.
def merge(self, other: "TileMetadata") -> "TileMetadata":
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nfx : Refactored this method also to an implementation that is stateless

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, the right way

replace_database_in_query = functools.partial(dashboards.replace_database_in_query, database=database)
lakeview_dashboard = lakeview_dashboards.create_dashboard(folder, query_transformer=replace_database_in_query)
dashboard_metadata = DashboardMetadata.from_path(folder).replace_database(
catalog=catalog or None, database=database or None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
catalog=catalog or None, database=database or None
catalog=catalog or None, database=database or None,

nit

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -216,8 +217,8 @@ def __post_init__(self):
if not self.id:
self.id = self.path.stem if self.path is not None else ""

def update(self, other: "TileMetadata") -> None:
"""Update the tile metadata with another tile metadata.
def merge(self, other: "TileMetadata") -> "TileMetadata":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, the right way

query_transformer: Callable[[sqlglot.Expression], sqlglot.Expression] | None = None,
) -> Dashboard:
"""Create a dashboard from code, i.e. configuration and queries.
def create_dashboard(dashboard_metadata: DashboardMetadata) -> Dashboard:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like the entire create_dashboard method from here should be converted to a method on DashboardMetadata:

def as_lakeview(self) -> Dashboard:
  self.validate()
  datasets = self.get_datasets() # make get_datasets private
  layouts = self.get_layouts() # make get_layouts private
  page = Page(
    name=dashboard_metadata.display_name,
    display_name=dashboard_metadata.display_name,
    layout=layouts,
  )
  return Dashboard(datasets=datasets, pages=[page])

@nfx nfx merged commit 46875e7 into main Jul 11, 2024
8 checks passed
@nfx nfx deleted the feat/replace-database-in-query-where-existing-database branch July 11, 2024 09:14
nfx pushed a commit that referenced this pull request Jul 11, 2024
nfx added a commit that referenced this pull request Jul 11, 2024
* Added method to dashboards to get dashboard url ([#211](#211)). In this release, we have added a new method `get_url` to the `lakeview_dashboards` object in the `laksedashboard` library. This method utilizes the Databricks SDK to retrieve the dashboard URL, simplifying the code and making it more maintainable. Previously, the dashboard URL was constructed by concatenating the host and dashboard ID, but this new method ensures that the URL is obtained correctly, even if the format changes in the future. Additionally, a new unit test has been added for a method that gets the dashboard URL using the workspace client. This new functionality allows users to easily retrieve the URL for a dashboard using its ID and the workspace client.
* Extend replace database in query ([#210](#210)). This commit extends the database replacement functionality in the `DashboardMetadata` class, allowing users to specify which database and catalog to replace. The enhancement includes support for catalog replacement and a new `replace_database` method in the `DashboardMetadata` class, which replaces the catalog and/or database in the query based on provided parameters. These changes enhance the flexibility and customization of the database replacement feature in queries, making it easier for users to control how their data is displayed in the dashboard. The `create_dashboard` function has also been updated to use the new method for replacing the database and catalog. Additionally, the `TileMetadata` update method has been replaced with a new merge method, and the `QueryTile` and `Tile` classes have new properties and methods for handling content, width, height, and position. The commit also includes several unit tests to ensure the new functionality works as expected.
* Improve object oriented dashboard-as-code implementation ([#208](#208)). In this release, the object-oriented implementation of the dashboard-as-code feature has been significantly improved, addressing previous pull request comments ([#201](#201)). The `TileMetadata` dataclass now includes methods for updating and comparing tile metadata, and the `DashboardMetadata` class has been removed and its functionality incorporated into the `Dashboards` class. The `Dashboards` class now generates tiles, datasets, and layouts for dashboards using the provided `query_transformer`. The code's readability and maintainability have been further enhanced by replacing the use of the `copy` module with `dataclasses.replace` for creating object copies. Additionally, updates have been made to the unit tests for dashboard functionality in the project, with new methods and attributes added to check for valid dashboard metadata and handle duplicate query or widget IDs, as well as to specify the order in which tiles and widgets should be displayed in the dashboard.
@nfx nfx mentioned this pull request Jul 11, 2024
nfx added a commit that referenced this pull request Jul 11, 2024
* Added method to dashboards to get dashboard url
([#211](#211)). In this
release, we have added a new method `get_url` to the
`lakeview_dashboards` object in the `laksedashboard` library. This
method utilizes the Databricks SDK to retrieve the dashboard URL,
simplifying the code and making it more maintainable. Previously, the
dashboard URL was constructed by concatenating the host and dashboard
ID, but this new method ensures that the URL is obtained correctly, even
if the format changes in the future. Additionally, a new unit test has
been added for a method that gets the dashboard URL using the workspace
client. This new functionality allows users to easily retrieve the URL
for a dashboard using its ID and the workspace client.
* Extend replace database in query
([#210](#210)). This commit
extends the database replacement functionality in the
`DashboardMetadata` class, allowing users to specify which database and
catalog to replace. The enhancement includes support for catalog
replacement and a new `replace_database` method in the
`DashboardMetadata` class, which replaces the catalog and/or database in
the query based on provided parameters. These changes enhance the
flexibility and customization of the database replacement feature in
queries, making it easier for users to control how their data is
displayed in the dashboard. The `create_dashboard` function has also
been updated to use the new method for replacing the database and
catalog. Additionally, the `TileMetadata` update method has been
replaced with a new merge method, and the `QueryTile` and `Tile` classes
have new properties and methods for handling content, width, height, and
position. The commit also includes several unit tests to ensure the new
functionality works as expected.
* Improve object oriented dashboard-as-code implementation
([#208](#208)). In this
release, the object-oriented implementation of the dashboard-as-code
feature has been significantly improved, addressing previous pull
request comments
([#201](#201)). The
`TileMetadata` dataclass now includes methods for updating and comparing
tile metadata, and the `DashboardMetadata` class has been removed and
its functionality incorporated into the `Dashboards` class. The
`Dashboards` class now generates tiles, datasets, and layouts for
dashboards using the provided `query_transformer`. The code's
readability and maintainability have been further enhanced by replacing
the use of the `copy` module with `dataclasses.replace` for creating
object copies. Additionally, updates have been made to the unit tests
for dashboard functionality in the project, with new methods and
attributes added to check for valid dashboard metadata and handle
duplicate query or widget IDs, as well as to specify the order in which
tiles and widgets should be displayed in the dashboard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TECH DEBT] Dashboards class public methods have to work only with DashboardMetadata instances
2 participants